package org.cardoso.persistence.filter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;


public class FindByExample {
	
	private static final String SUFFIX_GET = "get"; 
	
	public static QueryFilter create(Object entity) {
		
		try {
		
			QueryFilter queryFilter = new QueryFilter();
			
			Field fields[] = getFieldsByClass(entity.getClass());
			
			for (Field field : fields) {
				
				for (Annotation annotation : field.getAnnotations()) {
					
					if (annotation instanceof javax.persistence.Column) {
						
						Object value = entity.getClass().getMethod(getNameInvokeMethod(field), null).invoke(entity, null);
						
						if (value != null)
							queryFilter.add(getKeyColumn(field), value);
						
					}
					
					if (annotation instanceof javax.persistence.JoinColumn) {
						
						Object entityChildren = entity.getClass().getMethod(getNameInvokeMethod(field), null).invoke(entity, null);
						
						if(entityChildren != null){
							
							Field [] fieldsChildren = getFieldsByClass(entityChildren.getClass());
							
							for (Field fieldChildren : fieldsChildren) {
								
								for (Annotation annotationChildren : fieldChildren.getAnnotations()) {
									
									if (annotationChildren instanceof javax.persistence.Column) {
										
										Object valueChildren = entityChildren.getClass().getMethod(getNameInvokeMethod(fieldChildren), null).invoke(entityChildren, null);
										
										if (valueChildren != null)
											queryFilter.add(getKeyJoinColumn(field, fieldChildren), valueChildren);
										
									}
								}
							}
						}
					}
				}
			}
			
			return queryFilter;
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
		
	}
	
	@SuppressWarnings("rawtypes")
	private static Field[] getFieldsByClass(Class entityClass) {
		return entityClass.getDeclaredFields();
	}

	private static String getNameInvokeMethod(Field field) {
		return SUFFIX_GET.concat(field.getName().substring(0,1).toUpperCase().trim().concat(field.getName().substring(1).trim()));
	}
	
	private static String getKeyColumn(Field field) {
		return field.getType().equals(String.class) ?  field.getName() + QueryFilter.LIKE : field.getName();
	}
	
	private static String getKeyJoinColumn(Field field, Field fieldChildren) {
		return fieldChildren.getType().equals(String.class) ?  field.getName() + "." + fieldChildren.getName() + QueryFilter.LIKE : field.getName() + "." + fieldChildren.getName();
	}
	
}